package com.lishem.rpc.client.zk;

import com.lishem.common.annotation.RpcClient;
import com.lishem.rpc.client.cache.ServiceRouteCache;
import com.lishem.rpc.client.channel.ProviderService;
import com.lishem.rpc.client.config.RpcClientConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.reflections.Reflections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;

/**
 * 注册服务拉取管理器
 */
@Component
@Slf4j
public class ServicePullManager {

    /**
     * ZK客户端工具
     */
    @Autowired
    private ZKit zKit;

    /**
     * 服务路由缓存
     */
    @Autowired
    private ServiceRouteCache serviceRouteCache;

    /**
     * RPC客户端配置
     */
    @Autowired
    private RpcClientConfiguration configuration;

    /**
     * 服务订阅处理接口,调用就会订阅所有
     */
    public void pullServiceFromZK() {
        //1、获取指定包下所有的有@RpcClient注解的接口  这里的参数是：com.lishem.api
        Reflections reflections = new Reflections(configuration.getRpcClientApiPackage());
        // 拿到这个包里所有包含 @RpcClient注解的类
        Set<Class<?>> typesAnnotatedWith = reflections.getTypesAnnotatedWith(RpcClient.class);
        if (!CollectionUtils.isEmpty(typesAnnotatedWith)) {
            for (Class<?> cls : typesAnnotatedWith) {
                // 接口名字
                String serviceName = cls.getName();
                //2、根据接口的名字去Zookeeper获取接口名字对应节点的数据->服务列表
                List<ProviderService> providerServices = zKit.getServiceInfos(serviceName);
                //3、缓存服务列表数据->ServiceRouteCache
                serviceRouteCache.addCache(serviceName, providerServices);
                //4、如果接口名字对应的节点数据发生变更，同步更新->订阅监听
                zKit.subscribeZKEvent(serviceName);
            }
        }
    }
}